package org.wsiz.vro.domain;

import static javax.persistence.EnumType.STRING;
import static javax.persistence.TemporalType.TIMESTAMP;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.Transient;
import javax.persistence.Version;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlTransient;

import org.apache.log4j.Logger;
import org.springframework.data.domain.Persistable;
import org.wsiz.vro.domain.enums.Civility;

import com.google.common.base.Objects;

/**
 * @author "Tomasz Marciniak"
 */
@Entity
@Table(name = "person")
public class Person implements Persistable<Integer> {
	private static final long serialVersionUID = 1L;

	@SuppressWarnings("unused")
	private static final Logger log = Logger.getLogger(Person.class);

	private Integer id;
	private Civility civility;
	private String firstName;
	private String lastName;
	private Date birthDate;
	private Integer version;

	public Person() {
	}

	public Person(Integer primaryKey) {
		setId(primaryKey);
	}

	@Override
	@Transient
	@XmlTransient
	public boolean isNew() {
		return getId() == null;
	}

	@Column(nullable = false, unique = true, precision = 10)
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Id
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	@Column(length = 2)
	@Enumerated(STRING)
	public Civility getCivility() {
		return civility;
	}

	public void setCivility(Civility civility) {
		this.civility = civility;
	}

	@Size(max = 255)
	@Column(name = "first_name")
	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	@Size(max = 255)
	@Column(name = "last_name")
	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	@Column(name = "birth_date", length = 29)
	@Temporal(TIMESTAMP)
	public Date getBirthDate() {
		return birthDate;
	}

	public void setBirthDate(Date birthDate) {
		this.birthDate = birthDate;
	}

	@Column(precision = 10)
	@Version
	public Integer getVersion() {
		return version;
	}

	public void setVersion(Integer version) {
		this.version = version;
	}

	/**
	 * Set the default values.
	 */
	public void initDefaultValues() {
	}

	@Override
	public boolean equals(Object other) {
		return this == other
				|| (other instanceof Person && hashCode() == other.hashCode());
	}

	private PersistableHashBuilder persistableHashBuilder = new PersistableHashBuilder();
	
	@Override
	public int hashCode() {
		return persistableHashBuilder.hash(this);
	}

	/**
	 * Construct a readable string representation for this {@link Person}
	 * instance.
	 */
	@Override
	public String toString() {
		return Objects.toStringHelper(this) //
				.add("id", getId()) //
				.add("civility", getCivility()) //
				.add("firstName", getFirstName()) //
				.add("lastName", getLastName()) //
				.add("birthDate", getBirthDate()) //
				.add("version", getVersion()) //
				.toString();
	}
}